package com.jk.vehicle.core.utils;

import lombok.extern.slf4j.Slf4j;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Date;

/**
 * @author cjc
 * @date 2018/08/25
 * 时间工具类
 */
@Slf4j
public class TimeUtil {

    /**
     * 根据传入的格式返回当前时间
     *
     * @param format
     * @return
     */
    public static String getCurrentTime(String format) {
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(cal.getTime());
    }

    /**
     * 返回字符串解析的时间
     */
    public static Date parseDate(String date, String format) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.parse(date);
    }

    /**
     * 格式话日期为yyyy-MM-dd输出
     *
     * @param date
     * @return
     */
    public static String formatDate(Date date, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(date);
    }

    /**
     * 判断是否为日期格式
     *
     * @param date
     * @param format
     * @return
     */
    public static boolean isDate(String date, String format) {
        boolean flag = true;
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            sdf.parse(date);
        } catch (Exception e) {
            flag = false;
        }
        return flag;
    }

    /**
     * 指定时间 + day 天
     *
     * @param format
     * @param day
     * @return
     */
    public static String dateAddDay(Date date, int day, String format) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DAY_OF_MONTH, day);
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(cal.getTime());
    }

	/**
	 * 指定时间 + day 天
	 * @param date
	 * @param day
	 * @param format
	 * @return
	 * @throws ParseException
	 */
    public static String dateAddDay(String date, int day, String format) throws ParseException {
    	return dateAddDay(parseDate(date, format), day, format);
	}

    /**
     * 当前时间 + day 天
     *
     * @param format
     * @param day
     * @return
     */
    public static String dateAddDay(int day, String format) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_MONTH, day);
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(cal.getTime());
    }

    /**
     * 时间戳转换成日期格式字符串
     *
     * @param seconds
     * @param format
     * @return
     */
    public static String timeStamp2Date(String seconds, String format) {
        if (seconds == null || seconds.isEmpty()) {
            return "";
        }
        if (format == null || format.isEmpty()) {
            format = "yyyy-MM-dd HH:mm:ss";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(new Date(Long.valueOf(seconds)));
    }

    /**
     * 将时间格式转换成时间戳
     */
    public static String changeTime(String tempTime) {
        if (tempTime == null) {
            return "";
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        try {
            date = simpleDateFormat.parse(tempTime);
        } catch (ParseException e) {
            log.error(e.getMessage());
        }
        long ts = date.getTime();
        String time = String.valueOf(ts);
        return time;
    }

	/**
	 * 将时间戳转换成日期时间格式
	 */
	public static Date changeTimeFormat(String time) {

		Long lt = new Long(time);
		Date newTime = new Date(lt);
		return newTime;
	}

	/**
	 * 验证时间格式
	 * @param str 时间字符串
	 * @return 格式是否正确
	 */
	public static boolean isValidDate(String str, String format) {
		boolean convertSuccess = true;
		// 指定日期格式为四位年/两位月份/两位日期，注意yyyy/MM/dd区分大小写；
		SimpleDateFormat dateFormat = new SimpleDateFormat(format);
		try {
			// 设置lenient为false.
			// 否则SimpleDateFormat会比较宽松地验证日期，比如2007/02/29会被接受，并转换成2007/03/01
			dateFormat.setLenient(false);
			dateFormat.parse(str);
		} catch (ParseException e) {
			// 如果throw java.text.ParseException或者NullPointerException，就说明格式不对
			convertSuccess = false;
		}
		return convertSuccess;
	}

    /**
     * 根据日期获取日期当前周的周一日期
     * @param date 日期
     * @return 结果
     */
    public static Date getWeekFirstDay(final Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int weekday = cal.get(Calendar.DAY_OF_WEEK);//当前日期是周几
        if(weekday == 1){//如果是周日,减一
            cal.add(Calendar.DAY_OF_MONTH,-1);
        }
        cal.setFirstDayOfWeek(Calendar.MONDAY);//周一
        int dy = cal.get(Calendar.DAY_OF_WEEK);
        cal.add(Calendar.DATE,cal.getFirstDayOfWeek() - dy);

        return cal.getTime();
    }

    /**
     * 获取日期所在周的周日的日期
     * @param date 日期
     * @return 结果
     */
    public static Date getWeekLastDay(final Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int weekday = cal.get(Calendar.DAY_OF_WEEK);//当前日期是周几
        if(weekday != 1){
            cal.add(Calendar.DATE,8 - weekday);
            return cal.getTime();
        }

        return cal.getTime();
    }

    /**
     * 根据日期获得所在月份的第一天的日期
     * @param date 日期
     * @return 结果
     */
    public static Date getFirstDayDateOfMonth(final Date date) {
        final Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        final int last = cal.getActualMinimum(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, last);
        return cal.getTime();
    }

    /**
     * 根据日期获得所在月份的最后一天的日期
     * @param date 日期
     * @return 结果
     */
    public static Date getLastDayOfMonth(final Date date) {
        final Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        final int last = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, last);
        return cal.getTime();
    }

    /**
     * 获取日期对应当年的第几周
     * @param date 需要查询的日期
     * @return 结果
     */
    public static int getWeekOfYear(final Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.setTime(date);

        return calendar.get(Calendar.WEEK_OF_YEAR);
    }

    /**
     * LocalDate转Date
     * @param localDate
     * @return
     */
    public static Date localDate2Date(LocalDate localDate) {
        if (null == localDate) {
            return null;
        }
        ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault());
        return Date.from(zonedDateTime.toInstant());
    }

    /**
     * Date转LocalDate
     * @param date
     */
    public static LocalDate date2LocalDate(Date date) {
        if(null == date) {
            return null;
        }
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
    }

    /**

     * 计算两个日期之间相差的天数
     * @param minDate 较小的时间
     * @param maxDate 较大的时间
     * @return 相差天数
     */
    public static int daysBetween(Date minDate,Date maxDate)
    {
        Calendar cal = Calendar.getInstance();
        cal.setTime(minDate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(maxDate);
        long time2 = cal.getTimeInMillis();
        long between_days=(time2-time1)/(1000*3600*24);
        return Integer.parseInt(String.valueOf(between_days));
    }
}
